
%option nounput
%option yylineno
%{
	#include "util.h"
	#include "tiger.tab.h"
	//
	#include <stdlib.h>
	#include <string.h>

	int tigerwrap(void)
	{
		return 1;
	}

	//count the token number
	int tokenNum = 0;
	int tokenRun(){
		tokenNum ++;
		return tokenNum;
	}

	//helper function
	char* strdup(const char*tokenStr)
	{
		int tokenLen = strlen(tokenStr);
		char*tmpStr = (char*)malloc(sizeof(char)*(tokenLen+1));
		strcpy(tmpStr,tokenStr);
		return tmpStr;
	}
%}

%s IN_COMMENT
%s IN_STRING

%%
"," {tigerlval.ipos = tokenRun();return COMMA;}
":" {tigerlval.ipos = tokenRun();return COLON;}
";" {tigerlval.ipos = tokenRun();return SEMICOLON;}
"." {tigerlval.ipos = tokenRun();return DOT;}
"(" {tigerlval.ipos = tokenRun();return LPAREN;}
")" {tigerlval.ipos = tokenRun();return RPAREN;}
"[" {tigerlval.ipos = tokenRun();return LBRACK;}
"]" {tigerlval.ipos = tokenRun();return RBRACK;}
"{" {tigerlval.ipos = tokenRun();return LBRACE;}
"}" {tigerlval.ipos = tokenRun();return RBRACE;}
"+" {tigerlval.ipos = tokenRun();return PLUS;}
"-" {tigerlval.ipos = tokenRun();return MINUS;}
"*" {tigerlval.ipos = tokenRun();return TIMES;}
"/" {tigerlval.ipos = tokenRun();return DIVIDE;}
"==" {tigerlval.ipos = tokenRun();return EQ;}
"!=" {tigerlval.ipos = tokenRun();return NEQ;}
"<" {tigerlval.ipos = tokenRun();return LT;}
"<=" {tigerlval.ipos = tokenRun();return LE;}
">" {tigerlval.ipos = tokenRun();return GT;}
">=" {tigerlval.ipos = tokenRun();return GE;}
"&&" {tigerlval.ipos = tokenRun();return AND;}
"||" {tigerlval.ipos = tokenRun();return OR;}
":=" {tigerlval.ipos = tokenRun();return ASSIGN;}
"array" {tigerlval.ipos = tokenRun();return ARRAY;}
"if"    {tigerlval.ipos = tokenRun();return IF;}
"then"  {tigerlval.ipos = tokenRun();return THEN;}
"else"  {tigerlval.ipos = tokenRun();return ELSE;}
"while" {tigerlval.ipos = tokenRun();return WHILE;}
"for"   {tigerlval.ipos = tokenRun();return FOR;}
"to"    {tigerlval.ipos = tokenRun();return TO;}
"do"    {tigerlval.ipos = tokenRun();return DO;}
"let"   {tigerlval.ipos = tokenRun();return LET;}
"in"    {tigerlval.ipos = tokenRun();return IN;}
"end"   {tigerlval.ipos = tokenRun();return END;}
"of"    {tigerlval.ipos = tokenRun();return OF;}
"break" {tigerlval.ipos = tokenRun();return BREAK;}
"nil"   {tigerlval.ipos = tokenRun();return NIL;}
"type"  {tigerlval.ipos = tokenRun();return TYPE;}
"function" {tigerlval.ipos = tokenRun();return FUNCTION;}
"var"      {tigerlval.ipos = tokenRun();return VAR;}

[0-9]+ {tigerlval.ipos = tokenRun(); tigerlval.ival = atoi(yytext); return INT;}
[a-zA-Z_][a-zA-z0-9_]+ {tigerlval.ipos = tokenRun(); tigerlval.sval = strdup(yytext); return ID;}


<INITIAL>"\""  BEGIN(IN_STRING);//eat string
<IN_STRING>{
	"\""    ; tigerlval.ipos = tokenRun(); BEGIN(INITIAL); return STRING;
	[^\"]*  ; tigerlval.sval = strdup(yytext);
}


<INITIAL>{
	"//"[^\n]* printf("");       // eat single line comment
	"/*"       BEGIN(IN_COMMENT);// eat comment chunks
}
<IN_COMMENT>{
	"*/"	BEGIN(INITIAL);
	[^*\n]+	// eat comment in chunks
	"*"		// eat the lone star
}
" "  {}
"\t" {}
"\n" {}
. {printf("illegal token\n");}

%%


/*
int exp_error( const char *s )
{
    int i;
    printf("error is called\n");
    return 0;
}
*/
